#pragma once
#include <iostream>
#include <string>
#include <typeinfo>
#include <unistd.h>
#include <assert.h>
//any
namespace MyAny
{
    class Any
    {
    private:
        //内部父类
        class Holder
        {
        public:
            virtual const std::type_info& Type() = 0;
            virtual Holder* Clone() = 0;
        };
        //模板子类
        template<class T>
        class PlaceHolders:public Holder
        {
        public:
            PlaceHolders(const T& val) : _val(val){}
            ~PlaceHolders()
            {}
            const std::type_info& Type() override
            {
                return typeid(T);
            }
            Holder* Clone() override
            {
                return new PlaceHolders(_val);
            }
        public:
            T _val;
        };
        Any& Swap(Any& other)
        {
            std::swap(_obj,other._obj);
            return *this;
        }
        Holder* _obj = nullptr;
    public:
        Any(){}
        ~Any()
        {
            if(_obj) delete _obj;
        }
        Any(const Any& other) : _obj(other._obj ? (other._obj)->Clone() : nullptr)
        {}
        template<typename T>
        Any(const T& val)
        {
            if(_obj == nullptr) _obj = new PlaceHolders<T>(val);
        }
        //获取any管理的资源
        template<typename T>
        T* get()
        {
            assert(typeid(T) == _obj->Type() && _obj != nullptr);
            return &((PlaceHolders<T>*)_obj)->_val;
        }
        //重载赋值
        Any& operator=(const Any& other)
        {
            Any(other).Swap(*this);
            return *this;
        }
        template<typename T>
        Any& operator=(const T& val)
        {
            Any(val).Swap(*this);
            return *this;
        }
    };
}